package com.input;

/**
 * @Author: clm
 * @Date: 2018-10-16
 */

public class GameAction {
    /**标准游戏行为*/
    public final static int NORMAL = 0;
    /**初击有效游戏行为*/
    public final static int DETECT_INIAL_PRESS_ONLY = 1;

    /**状态:按下键*/
    public final static int STATE_PRESSED = 0;
    /**状态:释放键*/
    public final static int STATE_RELEASED = 1;
    /**状态:等待键释放*/
    public final static int STATE_WAITING_FOR_RELEASED = 2;

    /**此动作名称*/
    public String name;
    /**此动作此刻x的状态*/
    private int state;
    /**此动作属于的类型行为*/
    private int behavior;
    /**记录按下键的次数/鼠标移动的距离*/
    private int amount;

    /**构建新的指定名称的游戏动作,具有标准行为*/
    public GameAction(String name) {
        this(name, NORMAL);
    }

    /**构建新的指定名称的游戏动作,具有指定行为*/
    public GameAction(String name, int behavior){
        this.name = name;
        this.behavior = behavior;
    }

    /**复位此游戏动作,使其就像没有按下一样*/
    public synchronized void reset() {
        this.amount = 0;//将此游戏动作的按下记录标识置为0
        this.state = STATE_RELEASED;//将此游戏动作的状态置为"释放状态"
    }

    /**描述此游戏动作发生单击,即按下,释放*/
    public synchronized void tap(){
        press();//按下
        release();//释放
    }

    /**描述此游戏动作发生按下*/
    public synchronized void press() {
        press(1);//描述紧接着上次又按下一次
    }

    /**描述此游戏动作发生按下指定的次数/描述此动作为鼠标时发生移动了指定的距离*/
    public synchronized void press(int amount){
        if(state != STATE_WAITING_FOR_RELEASED){//如果状态不为"等待释放状态"
            this.amount += amount;//增量此游戏动作的按下次数记录器
            this.state = STATE_PRESSED;//标识此游戏动作的状态为"按下"
        }
    }

    /**描述此游戏动作发生释放*/
    public void release() {
        state = STATE_RELEASED;//标识此游戏动作的状态为"释放"
    }

    /**描述此游戏动作此刻x是否按下了,即表示上次检查以来键是否按下*/
    public synchronized boolean isPressed() {
        return (getAmount() != 0);//返回时刻点x-3到了此刻点x这过程段是否有发生按下记录.
    }

    /**描述此游戏动作从时刻点x-3到了此刻x这过程段,按下了的次数有多少,即表示上次检查以来键按下的次数/鼠标移动的距离</br>
     * 这个方法将返回x-3 -> x时间段的按下的次数,</br>
     * 只有这个方法时刻点x调用执行了,返回reVal后,那么amount才被置为0.但是返回的是x-1时刻点的amount值,x-1时刻点amount赋给了reVal,所以但是返回的是reVal.
     * */
    public synchronized int getAmount(){
        int reVal = this.amount;

		/*做一定判断*/
        if(reVal != 0){
            if(state == STATE_RELEASED){//如果到了此刻x,然而在此刻点x,键释放了,那么,应该将次数记录器复位,但是,此刻点x返回的是从x-3 --> x这段期间按下的次数,所以我们设置的是amount,但是此刻点x刻度,我们返回值是reVal.重设amount,下个时刻点x+1,在x-x+1过程段,如果没有发生按下,下个时刻点x+1来检测时,reVal就不会有值了.
                amount = 0;
            }
            else if(behavior == DETECT_INIAL_PRESS_ONLY){//如果此游戏动作的初击有效行为的动作,那么将状态置为"等待释放状态",从而以后的按下,即press()调用将无效,直到释放后,状态被设置为其他状态.并将次数记录器置为0,以便下次x+1时刻点刻度点来检测时,reVal的值就不会有了.
                state = STATE_WAITING_FOR_RELEASED;//置为"等待释放状态"
                amount = 0;
            }
        }

        return reVal;//返回的是reVal
    }
}

